#include<iostream>
#include<graphics.h> //easyx图形库的头文件
#include<ctime>
#include"tools.h"
#include"vector2.h"

#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")

using namespace std;

#define WIN_WIDTH 1000
#define WIN_HEIGHT 600

enum { WAN_DOU, XIANG_RI_KUI,ZHI_WU_COUNT };

IMAGE imgBg;//表示背景图片
IMAGE imgBar;
IMAGE imgCards[ZHI_WU_COUNT];
IMAGE* imgZhiWu[ZHI_WU_COUNT][20];

int curX, curY;//当前选中的植物，在移动过程中的位置
int curZhiWu;  //0：没有选中，1：选择了第一种植物……

class zhiwu
{
public:
	int type;         //0：没有植物  1：第一种植物
	int frameindex;   //序列帧的序号
	int shootTimer;
	int deadTime;
	int timer;
	int x, y;
	bool beate;//是否在被僵尸吃
};
class zhiwu map[3][9];

class sunshineBall
{
public:
	float x, y;
	int frameIndex;//显示当前的图片帧的序号
	int destY;//飘落的目标位置的y坐标
	bool used;//是否在使用
	int timer;
	float movex;
	float movey;
};
class sunshineBall balls[10];//创建一个池
IMAGE imgSunshineBall[29];
int sunshine;

class zm
{
public:
	float x, y;
	int row;
	int frameIndex;
	bool used;
	float speed;
	int blood;
	bool dead;
	bool eating;//正在吃植物
};
IMAGE imgZMeat[21];
IMAGE imgZM[22];
IMAGE imgZmdead[20];
class zm zms[10];

class bullet
{
public:
	int x, y;
	int row;
	int speed;
	bool used;
	bool blast;//是否发生爆炸
	int frameIndex;//帧序号
};
IMAGE imgbeginbullet;
IMAGE imgendbullet[4];
class bullet bullets[30];

bool fileExist(char* name)
{
	FILE* fp;
	fopen_s(&fp,name, "r");
	if (fp == NULL)
	{
		return false;
	}
	else
	{
		fclose(fp);
		return true;
	}
}

void gameInit()
{
	//记载背景图片
	loadimage(&imgBg, "res/bg.jpg");
	loadimage(&imgBar, "res/bar5.png");

	memset(imgZhiWu, 0, sizeof(imgZhiWu));//将数组中的值全设为0
	memset(map, 0, sizeof(map));

	//初始化植物卡牌
	char name[64];
	for (int i = 0; i < ZHI_WU_COUNT; i++)
	{
		//生成植物卡牌的文件名
		sprintf_s(name, sizeof(name), "res/Cards/card_%d.png", i + 1);
		loadimage(&imgCards[i], name);
		
		for (int j = 0; j < 20; j++)
		{
			sprintf_s(name, sizeof(name), "res/zhiwu/%d/%d.png", i,j + 1);
		    //先判断文件是否存在
			if (fileExist(name))
			{
				imgZhiWu[i][j] = new IMAGE;
				loadimage(imgZhiWu[i][j], name);
			}
			else break;
		}
	}

	curZhiWu = 0;
	sunshine = 50;

	//生成阳光的文件名
	memset(balls, 0, sizeof(balls));
	char shape[29];
	for (int i = 0; i < 29; i++)
	{
		sprintf_s(shape, sizeof(shape), "res/sunshine/%d.png", i + 1);
		loadimage(&imgSunshineBall[i], shape);
	}

	//初始化僵尸
	memset(zms, 0, sizeof(zms));
	char stride[22];
	for (int i = 0; i < 22; i++)
	{
		sprintf_s(stride, sizeof(stride), "res/zm/%d.png", i + 1);
		loadimage(&imgZM[i], stride);
	}

	//初始化子弹
	memset(bullets, 0, sizeof(bullets));
	loadimage(&imgbeginbullet, "res/bullets/PeaNormal/PeaNormal_0.png");
	loadimage(&imgendbullet[3], "res/bullets/bullet_blast.png");
	for (int i = 0; i < 3; i++)
	{
		float k = (i + 1) * 0.2;
		loadimage(&imgendbullet[i], "res/bullets/bullet_blast.png", imgendbullet[3].getwidth() * k, imgendbullet[3].getwidth() * k, true);
	}

	//初始化僵尸死亡
	char zmdead[20];
	for (int i = 0; i < 20; i++)
	{
		sprintf_s(zmdead, sizeof(zmdead), "res/zm_dead/%d.png", i + 1);
		loadimage(&imgZmdead[i], zmdead);
	}

	//初始化僵尸吃植物
	char zmeat[21];
	for (int i = 0; i < 21; i++)
	{
		sprintf_s(zmeat, sizeof(zmeat), "res/zm_eat/%d.png", i + 1);
		loadimage(&imgZMeat[i], zmeat);
	}

	//配置随机种子
	srand((unsigned int)time(NULL));

	//创建游戏的图形窗口
	initgraph(WIN_WIDTH, WIN_HEIGHT,1);

	//设置字体
	LOGFONT character;
	gettextstyle(&character);
	character.lfHeight = 27;
	character.lfWeight = 25;
	strcpy_s(character.lfFaceName, "Segoe UI Black");//设置字体
	character.lfQuality = ANTIALIASED_QUALITY;//抗锯齿效果
	settextstyle(&character);
	setbkmode(TRANSPARENT);//设置字体背景透明
	setcolor(BLACK);
}

void drawZM()
{
	int zmCount = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i < zmCount; i++)
	{
		if (zms[i].used)
		{
			IMAGE* img = NULL;
			if (zms[i].dead) img = imgZmdead;
			else if (zms[i].eating) img = imgZMeat;
			else img = imgZM;
			img += zms[i].frameIndex;

			putimagePNG(zms[i].x, zms[i].y, img);
		}
	}
}

void updateWindow()
{
	BeginBatchDraw();//开始缓冲

	putimage(0, 0, &imgBg);
	putimagePNG(250, 0, &imgBar);
	for (int i = 0; i < ZHI_WU_COUNT; i++)
	{
		int x = 335 + 65 * i;
		int y = 7;
		putimage(x, y, &imgCards[i]);
	}

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			if (map[i][j].type > 0)
			{
				int x = 250 + 82 * j;
				int y = 179 + 103 * i;
				int ZhiWuType = map[i][j].type - 1;
				int index = map[i][j].frameindex;
				putimagePNG(x, y, imgZhiWu[ZhiWuType][index]);
			}
		}
	}

	//输出阳光数
	char score[8];
	sprintf_s(score, sizeof(score), "%d", sunshine);
	outtextxy(285, 70, score);

	//渲染僵尸
	drawZM();

	//渲染豌豆子弹
	int bulletsMax = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i < bulletsMax; i++)
	{
		if (bullets[i].used)
		{
			if (bullets[i].blast)
			{
				IMAGE* img = &imgendbullet[bullets[i].frameIndex];
				putimagePNG(bullets[i].x, bullets[i].y, img);
			}
			else putimagePNG(bullets[i].x, bullets[i].y, &imgbeginbullet);
		}
	}

	//渲染阳光
	int ballMax = sizeof(balls) / sizeof(balls[0]);
	for (int i = 0; i < ballMax; i++)
	{
		if (balls[i].used || balls[i].movex != 0)
		{
			IMAGE* img = &imgSunshineBall[balls[i].frameIndex];
			putimagePNG(balls[i].x, balls[i].y, img);
		}
	}

	//渲染 拖动过程中的植物
	if (curZhiWu > 0)
	{
		IMAGE* img = imgZhiWu[curZhiWu - 1][0];
		putimagePNG(curX - img->getwidth() / 2, curY - img->getheight() / 2, img);
	}

	EndBatchDraw();//结束双缓冲
}

void collectSunshine(ExMessage* msg)
{
	int count = sizeof(balls) / sizeof(balls[0]);
	for (int i = 0; i < count; i++)
	{
		if (balls[i].used)
		{
			if (msg->x > balls[i].x && msg->x<balls[i].x + 79 && msg->y>balls[i].y && msg->y < balls[i].y + 79)
			{
				balls[i].used = false;
				mciSendString("play res/sunshine.mp3",0,0,0);
				//设置阳光球的偏移量
				float endX = 260;
				float endY = 0;
				float angle;
				angle = atan((balls[i].y - endY) / (balls[i].x - endX));
				balls[i].movex = 4 * cos(angle);
				balls[i].movey = 4 * sin(angle);
			}
		}
	}
}

void userClick()
{
	ExMessage msg;
	static int status = 0;
	if (peekmessage(&msg))
	{
		if (msg.message == WM_LBUTTONDOWN)
		{
			if (msg.x > 335 && msg.x < 335 + 65 * ZHI_WU_COUNT && msg.y < 96)
			{
				int index = (msg.x - 335) / 65;
				cout << index << endl;
				status = 1;
				curZhiWu = index + 1;
			}
			else
			{
				collectSunshine(&msg);
			}
		}
		else if (msg.message == WM_MOUSEMOVE && status == 1)
		{
			curX = msg.x;
			curY = msg.y;
		}
		else if (msg.message == WM_LBUTTONUP)
		{
			if (msg.x > 250 && msg.y > 179 && msg.y < 489)
			{
				int row = (msg.y - 179) / 103;
				int column = (msg.x - 250) / 81.8;
				
				if (map[row][column].type == 0)
				{
					map[row][column].type = curZhiWu;
					map[row][column].frameindex = 0; 
					map[row][column].shootTimer = 0;
				}
			}

			
			curZhiWu = 0;
			status = 0;
		}
	}
}

void createsunshine()
{
	static int count = 0;
	static int frequency = 200;
	count++;
	if (count >= frequency)
	{
		frequency = 100 + rand() % 200;
		count = 0;

		//从阳光池中取一个可以使用的
		int ballMax = sizeof(balls) / sizeof(balls[0]);

		int i;
		for (i = 0; i < ballMax && balls[i].used; i++);
		if (i >= ballMax) return;

		balls[i].used = true;
		balls[i].frameIndex = 0;
		balls[i].x = 260 + rand() % (640);
		balls[i].y = 80;
		balls[i].destY = 80 + rand() % (500);//
		balls[i].timer = 0;
		balls[i].movex = 0;
		balls[i].movey = 0;
	}
}

void updatesunshine()
{
	int ballMax = sizeof(balls) / sizeof(balls[0]);
	for (int i = 0; i < ballMax; i++)
	{
		if (balls[i].used)
		{
			balls[i].frameIndex = (balls[i].frameIndex + 1) % 29;
			if (balls[i].timer == 0)
			{
				balls[i].y += 2;
			}
			if (balls[i].y >= balls[i].destY)
			{
				balls[i].timer++;
				if (balls[i].timer > 100)
				{
					balls[i].used = false;
				}
			}
		}
		else if (balls[i].movex != 0)
		{
			float endX = 260;
			float endY = 0;
			float angle;
			angle = atan((balls[i].y - endY) / (balls[i].x - endX));
			balls[i].movex = 4 * cos(angle);
			balls[i].movey = 4 * sin(angle);
			balls[i].x -= balls[i].movex;
			balls[i].y -= balls[i].movey;
			if (balls[i].x < 260 || balls[i].y < 0)
			{
				balls[i].movex = 0;
				balls[i].movey = 0;
				sunshine += 25;
			}
		}
	}
}

void createzm()
{
	static int zmfrequency = 100;
	static int count = 0;
	count++;
	if (count > zmfrequency)
	{
		count = 0;
		zmfrequency = 250 + rand() % (100);
		int i;
		int zmMax = sizeof(zms) / sizeof(zms[0]);
		for (i = 0; i < zmMax && zms[i].used; i++);
		if (i < zmMax)
		{
			memset(&zms[i], 0, sizeof(zms[i]));
			zms[i].used = true;
			zms[i].row = rand() % 3;//0-2
			zms[i].y = 130 + (zms[i].row) * 103;
			zms[i].x = WIN_WIDTH;
			zms[i].frameIndex = 0;
			zms[i].speed = 1;
			zms[i].blood = 100;
			zms[i].dead = false;
			
		}
	}
}

void updatezm()
{
	int zmMax = sizeof(zms) / sizeof(zms[0]);

	static int number = 0;
	number++;
	if (number > 2)
	{
		number = 0;
		//更新僵尸的位置
		for (int i = 0; i < zmMax; i++)
		{
			if (zms[i].used)
			{
				zms[i].x -= zms[i].speed;
				if (zms->x < 100)
				{
					cout << "GAME OVER !" << endl;
					MessageBox(NULL, "over", "over", 0);//待优化
					exit(0);
				}
			}
		}
	}

	//实现僵尸动作
	static int count2 = 0;
	count2++;
	if (count2 > 2)
	{
		count2 = 0;
		for (int i = 0; i < zmMax; i++)
		{
			if (zms[i].used)
			{
				if (zms[i].dead)
				{
					zms[i].frameIndex++;
					if (zms[i].frameIndex >= 20)
					{
						zms[i].used = false;
					}
				}
				else if (zms[i].eating)
				{
					zms[i].frameIndex = (zms[i].frameIndex + 1) % 21;
				}
				else zms[i].frameIndex = (zms[i].frameIndex + 1) % 22;
			}
		}
	}
}

void shoot()
{
	int lines[3] = { 0 };
	int zmCount = sizeof(zms) / sizeof(zms[0]);
	int dangerX = WIN_WIDTH - 100;
	int bulletMax = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i < zmCount; i++)
	{
		if (zms[i].used && zms[i].x < dangerX)
		{
			lines[zms[i].row] = 1;
		}
	}
	int k;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			if (map[i][j].type == WAN_DOU + 1 && lines[i] != 0)
			{
				map[i][j].shootTimer++;
				if (map[i][j].shootTimer > 20)
				{
					map[i][j].shootTimer = 0;
					for (k = 0; k < bulletMax && bullets[k].used; k++);
					if (k < bulletMax)
					{
						bullets[k].used = true;
						bullets[k].row = i;
						bullets[k].speed = 15;
						bullets[k].blast = false;
						bullets[k].frameIndex = 0;
						int zwX = 250 + 82 * j;
						int zwY = 179 + 103 * i;
						bullets[k].x = zwX + imgZhiWu[map[i][j].type - 1][0]->getwidth() - 10;
						bullets[k].y = zwY + 10;
					}
				}
			}
		}
	}
}

void updatebullet()
{
	int countMax = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i < countMax; i++)
	{
		if (bullets[i].used)
		{
			bullets[i].x += bullets[i].speed;
			if (bullets[i].x > WIN_WIDTH)
			{
				bullets[i].used = false;
			}
			if (bullets[i].blast)
			{
				bullets[i].frameIndex++;
				if (bullets[i].frameIndex > 3)
				{
					bullets[i].used = false;
				}
			}
		}
	}
}

void collisionCheck()
{
	int bcount = sizeof(bullets) / sizeof(bullets[0]);
	int zcount = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i < bcount; i++)
	{
		if (!bullets[i].used || bullets[i].blast)
		{
			continue;
		}
		for (int j = 0; j < zcount; j++)
		{
			if (!zms[j].used) continue;
			int x1 = zms[j].x + 80;
			int x2 = zms[j].x + 110;
			int x = bullets[i].x;
			if (!zms[j].dead && x > x1 && x < x2 && bullets[i].row == zms[j].row)
			{
				zms[j].blood -= 10;
				bullets[i].blast = true;
				bullets[i].speed = 0;

				if (zms[j].blood <= 0)
				{
					zms[j].dead = true;
					zms[j].speed = 0;
					zms[j].frameIndex = 0;
				}
			}
		}
	}
	for (int i = 0; i < zcount; i++)
	{
		if (zms[i].dead || !zms[i].used) continue;

		for (int j = 0; j < 9; j++)
		{
			if (map[zms[i].row][j].type == 0) continue;
			int x1 = 260 + 82 * j;
			int x2 = 310 + 82 * j;
			int x3 = zms[i].x + 80;
			if (x3 > x1 && x3 < x2)
			{
				if (zms[i].eating)
				{
					//zms[i].frameIndex++;
					map[zms[i].row][j].deadTime++;
					if (map[zms[i].row][j].deadTime > 100)
					{
						map[zms[i].row][j].type = 0;
						map[zms[i].row][j].deadTime = 0;
						zms[i].speed = 1;
						zms[i].eating = false;
						zms[i].frameIndex = 0;
					}
				}
				else
				{
					zms[i].eating = true;
					map[zms[i].row][j].beate = true;
					zms[i].speed = 0;
					zms[i].frameIndex = 0;
				}
			}
			
		}
	}
}

void updateGame()
{
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			if (map[i][j].type > 0)
			{
				map[i][j].frameindex++;
				int ZhiWuType = map[i][j].type - 1;
				int index = map[i][j].frameindex;
				if (imgZhiWu[ZhiWuType][index]==NULL)
				{
					map[i][j].frameindex = 0;
				}
			}
		}
	}

	createsunshine();//创建阳光
	updatesunshine();//更新阳光的状态

	createzm();//创建僵尸
	updatezm();//更新僵尸的状态

	shoot();//发射豌豆
	updatebullet();//更新豌豆子弹

	collisionCheck();//实现子弹的碰撞检测
}

void startUI()
{
	IMAGE imgBg, imgMenu1, imgMenu2;
	loadimage(&imgBg, "res/menu.png");
	loadimage(&imgMenu1, "res/menu1.png");
	loadimage(&imgMenu2, "res/menu2.png");
	int flag = 0;

	while (1)
	{
		BeginBatchDraw();
		putimage(0, 0, &imgBg);
		putimagePNG(475, 75, flag ? &imgMenu2 : &imgMenu1);
		EndBatchDraw();

		ExMessage msg;
		if (peekmessage(&msg))
		{
			if (msg.message == WM_LBUTTONDOWN && msg.x > 475 && msg.x < 806 && msg.y>75 && msg.y < 220)
			{
				flag = 1;
			}
			else if (msg.message == WM_LBUTTONUP && flag==1)
			{
				return;
			}
		}
		EndBatchDraw();
	}
}

int main()
{
	
	gameInit();
	startUI();

	int timer = 0;
	bool flag = true;
	while (1)
	{
		userClick();
		timer += getDelay();
		if (timer > 50)
		{
			flag = true;
			timer = 0;
		}
		
		if (flag)
		{
			flag = false;
			updateWindow();
			updateGame();
		}

	}

	system("pause");
	return 0;
}